package com.yxq.mdt.app.application;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.multidex.MultiDex;

import com.alibaba.android.arouter.launcher.ARouter;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationListener;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.bumptech.glide.Glide;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMCmdMessageBody;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.chat.EMTextMessageBody;
import com.hyphenate.chat.adapter.message.EMAMessage;
import com.hyphenate.easeui.EaseConstant;
import com.hyphenate.easeui.EaseUI;
import com.hyphenate.easeui.domain.EaseUser;
import com.hyphenate.easeui.model.EaseAtMessageHelper;
import com.hyphenate.easeui.model.EaseNotifier;
import com.hyphenate.easeui.utils.EaseCommonUtils;
import com.hyphenate.util.EMLog;
import com.orhanobut.hawk.Hawk;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.socialize.PlatformConfig;
import com.umeng.socialize.UMShareAPI;
import com.umeng.socialize.UMShareConfig;
import com.yxq.mdt.app.BuildConfig;
import com.yxq.mdt.app.R;
import com.yxq.mdt.app.constant.Constant;
import com.yxq.mdt.app.constant.SPKey;
import com.yxq.mdt.app.glide.GlideHelper;
import com.yxq.mdt.app.modules.chat.ui.ChatActivity;
import com.yxq.mdt.app.modules.personal.bean.MyPersonalBean;
import com.yxq.mdt.app.modules.personal.model.UserModel;
import com.yxq.mdt.app.modules.socialcontact.ui.activity.VideoTakeChatActivity;
import com.yxq.mdt.app.modules.socialcontact.ui.activity.VoiceTakeChatActivity;
import com.yxq.mdt.app.net.ApiModel;
import com.yxq.mdt.app.utils.StringUtils;
import com.zlw.main.recorderlib.RecordManager;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import static com.hyphenate.chat.EMClient.TAG;


/**
 * @描述 程序入口
 * @作者 yd
 * @创建日期 2019/8/29 0029 09:50
 */
public class App extends Application {

    private static App instance;
    private static Stack<AppCompatActivity> activityStack;
    public static Context context;
    public static long APP_START_TIME;
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    private HashMap<String, MyPersonalBean> UserList;
    /**
     * EMEventListener
     */
    protected EMMessageListener messageListener = null;
    public boolean isVoiceCalling;
    public boolean isVideoCalling;

    static {
        //设置全局的Header构建器
        SmartRefreshLayout.setDefaultRefreshHeaderCreator((context, layout) -> {
            layout.setPrimaryColorsId(R.color.transparent, R.color.color_font_black);//全局设置主题颜色
            return new ClassicsHeader(context);
        });
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreator((context, layout) -> {
            //指定为经典Footer，默认是 BallPulseFooter
            return new ClassicsFooter(context).setDrawableSize(20);
        });
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(base);
        // 安装tinker
        Beta.installTinker();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        context = this;
        UserList = new HashMap<>();
        initARouter();
        initAudioRecord();
        initUmeng();
        initCache();
        initEmChat();
        setReceiver();
        initAMap();
        initUtils();
        initBugly();
    }

    private void initBugly() {
        //初始化
        if ("release".equals(BuildConfig.RELEASE)) {
            Bugly.init(context, "4708bc812f", false);
        } else {
            Bugly.init(context, "466c0671a1", true);
        }
        //禁止自动检测升级
        Beta.autoCheckUpgrade=false;
        Beta.initDelay = 1 * 1000;
    }

    private void initUtils() {
        ToastUtils.setBgColor(getResources().getColor(R.color.black_deep));
        ToastUtils.setMsgColor(getResources().getColor(R.color.white));
        ToastUtils.setGravity(Gravity.CENTER, 0, 0);
    }

    /**
     * 初始化友盟SDK
     */
    private void initUmeng() {
        UMShareConfig config = new UMShareConfig();
        config.isNeedAuthOnGetUserInfo(true);//每次都需要授权
        UMShareAPI.get(context).setShareConfig(config);

        UMConfigure.init(context, Constant.UmengAppKey, StringUtils.getAppMetaData(context, "UMENG_CHANNEL"), UMConfigure.DEVICE_TYPE_PHONE, null);
        UMConfigure.setLogEnabled(BuildConfig.DEBUG);// 打开统计SDK调试模式
        UMConfigure.setEncryptEnabled(!BuildConfig.DEBUG);
        MobclickAgent.setCatchUncaughtExceptions(!BuildConfig.DEBUG);// false-关闭错误统计功能；true-打开错误统计功能（默认打开）
        MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO);// 选用AUTO页面采集模式
        PlatformConfig.setWeixin(Constant.WECHAT_ID, Constant.WECHAT_SECRETKEY);
        PlatformConfig.setQQZone(Constant.QQ_ID, Constant.QQ_SECRETKEY);
    }

    /**
     * 注册环信电话，视频广播监听
     */
    private void setReceiver() {
        IntentFilter callFilter = new IntentFilter(EMClient.getInstance().callManager().getIncomingCallBroadcastAction());
        registerReceiver(new CallReceiver(), callFilter);
    }

    /**
     * 初始化高德地图
     */
    private void initAMap() {

        AMapLocationListener mLocationListener = aMapLocation -> {

        };
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
    }

    private class CallReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 拨打方username
            String from = intent.getStringExtra("from");
            // call type
            String type = intent.getStringExtra("type");
            //跳转到通话页面
            if (BuildConfig.DEBUG) {
                Log.e("环信", "收到来电：from=" + from + "type=" + type);
            }

            Intent intentCall = null;
            if ("voice".equals(type)) {
                isVoiceCalling = true;
                isVideoCalling = false;
                intentCall = new Intent(context, VoiceTakeChatActivity.class);
            } else if ("video".equals(type)) {
                isVideoCalling = true;
                isVoiceCalling = false;
                intentCall = new Intent(context, VideoTakeChatActivity.class);
            }
            intentCall.putExtra("from", from);
//            if(!EaseUI.getInstance().hasForegroundActivies()){
//                EMAMessage emaMessage = new EMAMessage();
//                emaMessage.setFrom(from);
//                EMMessage emMessage = new EMMessage(emaMessage);
//                EaseUI.getInstance().getNotifier().notify(emMessage);
//                return;
//            }
            intentCall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intentCall);
        }
    }

    /**
     * 初始化环信SDK
     */
    private void initEmChat() {

        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        // 如果APP启用了远程的service，此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
        // 默认的APP会在以包名为默认的process name下运行，如果查到的process name不是APP的process name就立即返回
        if (processAppName == null || !processAppName.equalsIgnoreCase(this.getPackageName())) {
            Log.e("环信", "enter the service process!");
            // 则此application::onCreate 是被service 调用的，直接返回
            return;
        }
        EMOptions options = new EMOptions();
        // 默认添加好友时，是不需要验证的，改成需要验证
        options.setAcceptInvitationAlways(false);
        //不自动登录
        options.setAutoLogin(false);
        //初始化
        EMClient.getInstance().init(this, options);
        //在做打包混淆时，关闭debug模式，避免消耗不必要的资源
        EMClient.getInstance().setDebugMode(BuildConfig.DEBUG);
        //环信UI界面初始化
        EaseUI.getInstance().init(this, options);
        EaseUI.getInstance().setUserProfileProvider(new EaseUI.EaseUserProfileProvider() {
            @Override
            public EaseUser getUser(String username) {
                if (TextUtils.isEmpty(username)) {
                    return null;
                }

                return null;
            }

            @Override
            public EaseUser setUserUI(String username, ImageView avatar, TextView nick) {
                return getUserInfo(username, avatar, nick);
            }
        });
        if (BuildConfig.DEBUG) {
            setNoticeProvider();
            //register message event listener
            registerMessageListener();
        }
    }

    private void setNoticeProvider() {
        //set notification options, will use default if you don't set it
        EaseUI.getInstance().getNotifier().setNotificationInfoProvider(new EaseNotifier.EaseNotificationInfoProvider() {

            @Override
            public String getTitle(EMMessage message) {
                //you can update title here
                return null;
            }

            @Override
            public int getSmallIcon(EMMessage message) {
                //you can update icon here
                return 0;
            }

            @Override
            public String getDisplayedText(EMMessage message) {
                // be used on notification bar, different text according the message type.
                String ticker = EaseCommonUtils.getMessageDigest(message, context);
                if (message.getType() == EMMessage.Type.TXT) {
                    ticker = ticker.replaceAll("\\[.{2,3}\\]", "[表情]");
                }
                EaseUser user = getUserInfo(message.getFrom(), null, null);
                if (user != null) {
//                    if(EaseAtMessageHelper.get().isAtMeMsg(message)){
//                        return String.format(context.getString(R.string.at_your_in_group), user.getNickname());
//                    }
                    return user.getNickname() + ": " + ticker;
                } else {
//                    if(EaseAtMessageHelper.get().isAtMeMsg(message)){
//                        return String.format(context.getString(R.string.at_your_in_group), message.getFrom());
//                    }
                    return message.getFrom() + ": " + ticker;
                }
            }

            @Override
            public String getLatestText(EMMessage message, int fromUsersNum, int messageNum) {
                // here you can customize the text.
                // return fromUsersNum + "contacts send " + messageNum + "messages to you";
                return null;
            }

            @Override
            public Intent getLaunchIntent(EMMessage message) {
                // you can set what activity you want display when user click the notification
                Intent intent = new Intent(context, ChatActivity.class);
                // open calling activity if there is call
                if (isVideoCalling) {
                    intent = new Intent(context, VideoTakeChatActivity.class);
                    intent.putExtra("from", message.getFrom());
                } else if (isVoiceCalling) {
                    intent = new Intent(context, VoiceTakeChatActivity.class);
                    intent.putExtra("from", message.getFrom());
                } else {
                    EMMessage.ChatType chatType = message.getChatType();
                    if (chatType == EMMessage.ChatType.Chat) { // single chat message
                        intent.putExtra("userId", message.getFrom());
                        intent.putExtra("chatType", EaseConstant.CHATTYPE_SINGLE);
                    } else { // group chat message
                        // message.getTo() is the group id
                        intent.putExtra("userId", message.getTo());
                        if (chatType == EMMessage.ChatType.GroupChat) {
                            intent.putExtra("chatType", EaseConstant.CHATTYPE_GROUP);
                        } else {
                            intent.putExtra("chatType", EaseConstant.CHATTYPE_CHATROOM);
                        }

                    }
                }
                return intent;
            }
        });
    }

    /**
     * Global listener
     * If this event already handled by an activity, you don't need handle it again
     * activityList.size() <= 0 means all activities already in background or not in Activity Stack
     */
    protected void registerMessageListener() {
        messageListener = new EMMessageListener() {
            @Override
            public void onMessageReceived(List<EMMessage> messages) {
                for (EMMessage message : messages) {
                    EMLog.d(TAG, "onMessageReceived id : " + message.getMsgId());
                    // 判断一下是否是会议邀请
//                    String confId = message.getStringAttribute(Constant.MSG_ATTR_CONF_ID, "");
//                    if(!"".equals(confId)){
//                        String password = message.getStringAttribute(Constant.MSG_ATTR_CONF_PASS, "");
//                        String extension = message.getStringAttribute(Constant.MSG_ATTR_EXTENSION, "");
//                        goConference(confId, password, extension);
//                    }
                    // in background, do not refresh UI, notify it in notification bar
                    if (!EaseUI.getInstance().hasForegroundActivies()) {
                        EaseUI.getInstance().getNotifier().notify(message);
                    }
                }
            }

            @Override
            public void onCmdMessageReceived(List<EMMessage> messages) {
                for (EMMessage message : messages) {
                    EMLog.d(TAG, "receive command message");
                    //get message body
                    EMCmdMessageBody cmdMsgBody = (EMCmdMessageBody) message.getBody();
                    final String action = cmdMsgBody.action();//获取自定义action
                    //获取扩展属性 此处省略
                    //maybe you need get extension of your message
                    //message.getStringAttribute("");
                    EMLog.d(TAG, String.format("Command：action:%s,message:%s", action, message.toString()));
                }
            }

            @Override
            public void onMessageRead(List<EMMessage> messages) {
            }

            @Override
            public void onMessageDelivered(List<EMMessage> message) {
            }

            @Override
            public void onMessageRecalled(List<EMMessage> messages) {
                for (EMMessage msg : messages) {
                    if (msg.getChatType() == EMMessage.ChatType.GroupChat && EaseAtMessageHelper.get().isAtMeMsg(msg)) {
                        EaseAtMessageHelper.get().removeAtMeGroup(msg.getTo());
                    }
//                    EMMessage msgNotification = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
//                    EMTextMessageBody txtBody = new EMTextMessageBody(String.format(appContext.getString(R.string.msg_recall_by_user), msg.getFrom()));
//                    msgNotification.addBody(txtBody);
//                    msgNotification.setFrom(msg.getFrom());
//                    msgNotification.setTo(msg.getTo());
//                    msgNotification.setUnread(false);
//                    msgNotification.setMsgTime(msg.getMsgTime());
//                    msgNotification.setLocalTime(msg.getMsgTime());
//                    msgNotification.setChatType(msg.getChatType());
//                    msgNotification.setAttribute(Constant.MESSAGE_TYPE_RECALL, true);
//                    msgNotification.setStatus(EMMessage.Status.SUCCESS);
//                    EMClient.getInstance().chatManager().saveMessage(msgNotification);
                }
            }

            @Override
            public void onMessageChanged(EMMessage message, Object change) {
                EMLog.d(TAG, "change:");
                EMLog.d(TAG, "change:" + change);
            }
        };

        EMClient.getInstance().chatManager().addMessageListener(messageListener);
    }

    private void setCallOptions() {
//        HeadsetReceiver headsetReceiver = new HeadsetReceiver();
//        IntentFilter headsetFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
//        appContext.registerReceiver(headsetReceiver, headsetFilter);

//        // min video kbps
//        int minBitRate = PreferenceManager.getInstance().getCallMinVideoKbps();
//        if (minBitRate != -1) {
//            EMClient.getInstance().callManager().getCallOptions().setMinVideoKbps(minBitRate);
//        }
//
//        // max video kbps
//        int maxBitRate = PreferenceManager.getInstance().getCallMaxVideoKbps();
//        if (maxBitRate != -1) {
//            EMClient.getInstance().callManager().getCallOptions().setMaxVideoKbps(maxBitRate);
//        }
//
//        // max frame rate
//        int maxFrameRate = PreferenceManager.getInstance().getCallMaxFrameRate();
//        if (maxFrameRate != -1) {
//            EMClient.getInstance().callManager().getCallOptions().setMaxVideoFrameRate(maxFrameRate);
//        }
//
//        // audio sample rate
//        int audioSampleRate = PreferenceManager.getInstance().getCallAudioSampleRate();
//        if (audioSampleRate != -1) {
//            EMClient.getInstance().callManager().getCallOptions().setAudioSampleRate(audioSampleRate);
//        }
//
//        /**
//         * This function is only meaningful when your app need recording
//         * If not, remove it.
//         * This function need be called before the video stream started, so we set it in onCreate function.
//         * This method will set the preferred video record encoding codec.
//         * Using default encoding format, recorded file may not be played by mobile player.
//         */
//        //EMClient.getInstance().callManager().getVideoCallHelper().setPreferMovFormatEnable(true);
//
//        // resolution
//        String resolution = PreferenceManager.getInstance().getCallBackCameraResolution();
//        if (resolution.equals("")) {
//            resolution = PreferenceManager.getInstance().getCallFrontCameraResolution();
//        }
//        String[] wh = resolution.split("x");
//        if (wh.length == 2) {
//            try {
//                EMClient.getInstance().callManager().getCallOptions().setVideoResolution(new Integer(wh[0]).intValue(), new Integer(wh[1]).intValue());
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//
//        // enabled fixed sample rate
//        boolean enableFixSampleRate = PreferenceManager.getInstance().isCallFixedVideoResolution();
//        EMClient.getInstance().callManager().getCallOptions().enableFixedVideoResolution(enableFixSampleRate);
//
//        // Offline call push
//        EMClient.getInstance().callManager().getCallOptions().setIsSendPushIfOffline(getModel().isPushCall());
    }

    private EaseUser getUserInfo(String username, ImageView avatar, TextView nick) {
        if (TextUtils.isEmpty(username)) {
            return null;
        }
        // To get instance of EaseUser, here we get it from the user list in memory
        // You'd better cache it if you get it from your server
        EaseUser user = null;
        if (username != null && UserList != null && UserList.containsKey(username)) {
            MyPersonalBean userBean = UserList.get(username);
            if (userBean != null) {
                if (avatar != null) {
                    GlideHelper.setLoadRoundImage(instance, userBean.getHeadimg(), R.mipmap.head_icon, avatar);
                }
                if (nick != null) {
                    nick.setText(userBean.getGsName());
                }
            }

            return null;
        }
        UserModel.getGaUserExtVoById(username.replaceAll("yxq", ""), new ApiModel.CommonCallback<MyPersonalBean>() {
            @Override
            public void onSuccess(MyPersonalBean myPersonalBean) {

                if (myPersonalBean != null) {
                    UserList.put("yxq" + myPersonalBean.getUserId(), myPersonalBean);
                    if (avatar != null) {
                        GlideHelper.setLoadRoundImage(instance, myPersonalBean.getHeadimg(), R.mipmap.head_icon, avatar);
                    }
                    if (nick != null) {
                        nick.setText(myPersonalBean.getGsName());
                    }
                } else {
                    if (avatar != null) {
                        avatar.setImageResource(R.mipmap.head_icon);
                    }
                    if (nick != null) {
                        nick.setText(username);
                    }
                }
                Hawk.put(SPKey.SP_KEY_USER_PERFECTTATIO_NUMBER, myPersonalBean.getPerfectRatio() + "");
            }

            @Override
            public void onError(String errMsg) {
                if (avatar != null) {
                    avatar.setImageResource(R.mipmap.head_icon);
                }
                if (nick != null) {
                    nick.setText(username);
                }
            }
        });
        // if user is not in your contacts, set inital letter for him/her
        if (user == null) {
            user = new EaseUser(username);
            EaseCommonUtils.setUserInitialLetter(user);
        }

        return user;
    }

    private void initAudioRecord() {
        /**
         * 参数1： Application 实例
         * 参数2： 是否打印日志
         */
        RecordManager.getInstance().init(instance, BuildConfig.DEBUG);
    }

    private void initCache() {

        APP_START_TIME = System.currentTimeMillis();
        Hawk.init(this).build();
    }


    private void initARouter() {
        //阿里路由框架
        if (BuildConfig.DEBUG) {    // 这两行必须写在init之前，否则这些配置在init过程中将无效
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)
        }
        ARouter.init(instance);
    }


    public static App getInstance() {
        return instance;
    }

    /**
     * add Activity 添加Activity到栈
     */
    public void addActivity(AppCompatActivity activity) {
        if (activityStack == null) {
            activityStack = new Stack<AppCompatActivity>();
        }
        activityStack.add(activity);
    }

    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity.finish();
        }
    }

    /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        if (activityStack == null) {
            return;
        }
        for (int i = 0, size = activityStack.size(); i < size; i++) {
            if (null != activityStack.get(i)) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }

    public void exit() {
        finishAllActivity();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Glide.get(this).clearMemory();
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        //如果切换到后台，清理掉内存缓存
        if (level == TRIM_MEMORY_UI_HIDDEN) {
            Glide.get(this).clearMemory();
        }
        Glide.get(this).onTrimMemory(level);
    }


    private String getAppName(int pID) {
        try {
            String processName = null;
            ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
            List l = am.getRunningAppProcesses();
            Iterator i = l.iterator();
            PackageManager pm = this.getPackageManager();
            while (i.hasNext()) {
                ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
                try {
                    if (info.pid == pID) {
                        processName = info.processName;
                        return processName;
                    }
                } catch (Exception e) {
                }
            }
            return processName;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


}
